package com.example.batterynotification;

import android.R.bool;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

public class CustomSeekBar extends View {
	private Paint paint;
	private Rect rect;
	private RectF outerRectF;
	private RectF innerRectF;
	private RectF strokeRectF;
	private int hight = 50;
	private int width= 800;
	private float innerLenght = 0;
	private Bitmap arrow;
	private LinearGradient backBarShader;
	private LinearGradient frontBarShader;
	private int padding=30;
	private int strokeWidth =5;
	private int currentLevel =0;
	private int minLevel=0;
	private int maxLevel=100;
	private int startingPositionx=0;
	 public int getMinLevel() {
		return minLevel;
	}

	public void setMinLevel(int minLevel) {
		this.minLevel = minLevel;
	}

	public int getMaxLevel() {
		return maxLevel;
	}

	public void setMaxLevel(int maxLevel) {
		this.maxLevel = maxLevel;
	}

	OnCustomSeekBarChangeListener mListener;
	public int getCurrentLevel() {
		return currentLevel;
	}

	public void setCurrentLevel(int currentLevel) {
		setCurrentLevel(currentLevel ,false);
	}

	public void setCurrentLevel(int currentLevel ,boolean calledOnTouch)
	{
		this.currentLevel = currentLevel;
		if(!calledOnTouch)
		{
			if(currentLevel <= maxLevel && currentLevel >= minLevel)
			{			
				this.currentLevel = currentLevel;
				innerLenght = /*startingPositionx*/ + (float)fromLevelToPostionx(currentLevel);
				rect = new Rect(0+padding/*+strokeWidth*/, 0+padding+strokeWidth, (int) innerLenght, hight);
				innerRectF = new RectF(rect);
				invalidate();
			}
		}
		
	}
	public CustomSeekBar(Context context, AttributeSet attrs) {
		super(context, attrs);



		paint = new Paint();
		hight+=padding;
		innerLenght+=padding;
		startingPositionx=0+padding+strokeWidth;
		rect = new Rect(startingPositionx, 0+padding+strokeWidth, width, hight);
		outerRectF = new RectF(rect);

		rect = new Rect(0+padding, 0+padding, width+strokeWidth, hight+strokeWidth);
		strokeRectF = new RectF(rect);
		
		rect = new Rect(startingPositionx, 0+padding+strokeWidth, 0, hight);
		innerRectF = new RectF(rect);

		arrow = BitmapFactory.decodeResource(context.getResources(),
				R.drawable.seek_bar_arrow);
		backBarShader =new LinearGradient(width, 0, 0, hight,Color.rgb(101,98,86), Color.WHITE, Shader.TileMode.REPEAT);
		frontBarShader =new LinearGradient(width, 0, 0, hight, Color.rgb(9, 43	,19),Color.rgb(57,221,78), Shader.TileMode.REPEAT);
		

	}

	@Override
	protected void onDraw(Canvas canvas) {
		//Draw the back bar
		paint.setShader(backBarShader);
		canvas.drawRoundRect(outerRectF, 50, 50, paint);
		paint.reset();
		//Draw stroke
		paint.setStyle(Paint.Style.STROKE);
		paint.setStrokeWidth(10);
		paint.setColor(Color.BLACK);
		canvas.drawRoundRect(strokeRectF, 50, 50, paint);
		paint.reset();
		//Draw the front bar
		paint.setShader(frontBarShader);
		canvas.drawRoundRect(innerRectF, 50, 50, paint);
		paint.reset();
		// super.onDraw(canvas);
		canvas.drawBitmap(arrow,innerLenght - arrow.getWidth() / 2, hight / 2, paint);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_DOWN
				|| event.getAction() == MotionEvent.ACTION_MOVE) {
			float eventX = event.getX();
			float eventY = event.getY();
			if (eventY < hight*3) //width*3 to give room for the finger 
			{
				moveSeekBar(eventX);
				return true;
			}
		}
		return super.onTouchEvent(event);
	}

	private void moveSeekBar(float eventX) {
		if(eventX <= width && eventX>= startingPositionx)
		{
			innerLenght = (int) eventX;
			setCurrentLevel(fromPostionxToLevel(eventX),true);
		}
		else if(eventX > width)
		{
			innerLenght=width;
			setCurrentLevel(fromPostionxToLevel((float)innerLenght),true);
		}
		else
		{ 
			innerLenght=startingPositionx;
			setCurrentLevel(fromPostionxToLevel((float)innerLenght),true);
		}
		rect = new Rect(0+padding/*+strokeWidth*/, 0+padding+strokeWidth, (int) innerLenght, hight);
		innerRectF = new RectF(rect);
		invalidate();
		//call the event
		if(mListener!=null)
			mListener.onProgressChanged(getCurrentLevel());
		
	}
	public int fromPostionxToLevel(Float x)
	{
		int level=0;

		float ratio =((float)(maxLevel-minLevel)/((float)(width - startingPositionx)));
		level=(int) (x*ratio);
		level-=(int) (startingPositionx*ratio);

		level+=minLevel;
		Log.i("LC", ""+level+" "+x);
		return level;
		
	}
	
	
	public double fromLevelToPostionx(int level)
	{
		double x = 0;
		double ratio =((float)(maxLevel-minLevel)/((float)(width - startingPositionx)));
		level -= minLevel;
		level += (int) (startingPositionx * ratio);
		x = ((double)level / ratio);
		Log.i("LC", ""+level+" "+x);
		return x;
		
	}
	
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		  int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
		    int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
		    this.setMeasuredDimension(width+padding,hight+ 50/*default bottom padding*/ );
		/*code snippet for future enhancement
		 *int desiredWidth = 100;
    int desiredHeight = 100;

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int width;
    int height;

    //Measure Width
    if (widthMode == MeasureSpec.EXACTLY) {
        //Must be this size
        width = widthSize;
    } else if (widthMode == MeasureSpec.AT_MOST) {
        //Can't be bigger than...
        width = Math.min(desiredWidth, widthSize);
    } else {
        //Be whatever you want
        width = desiredWidth;
    }

    //Measure Height
    if (heightMode == MeasureSpec.EXACTLY) {
        //Must be this size
        height = heightSize;
    } else if (heightMode == MeasureSpec.AT_MOST) {
        //Can't be bigger than...
        height = Math.min(desiredHeight, heightSize);
    } else {
        //Be whatever you want
        height = desiredHeight;
    }

    //MUST CALL THIS
    setMeasuredDimension(width, height); 
		 * 
		 * 
		 * 
		 * 
		 * 
		 * */
	}
	
	public void setOnCustomSeekBarChangeListener(
			OnCustomSeekBarChangeListener eventListener) {
		mListener = eventListener;
	}

}
